-- Lua Battle System - 战斗状态管理

local Logger = require("utils.logger")
local TableUtils = require("utils.table_utils")

local BattleState = {
    -- 战斗状态枚举
    states = {
        WAITING = "waiting",
        STARTING = "starting",
        IN_PROGRESS = "in_progress",
        ENDED = "ended"
    },
    
    -- 战斗基本信息
    battle_id = "",
    battle_state = "waiting",
    start_time = 0,
    end_time = 0,
    
    -- 队伍信息
    teams = {
        [1] = {
            name = "Team 1",
            characters = {},
            score = 0
        },
        [2] = {
            name = "Team 2",
            characters = {},
            score = 0
        }
    },
    
    -- 战斗角色列表
    characters = {},
    
    -- 回合信息
    current_turn = 0,
    max_turns = 100,
    turn_order = {},
    current_character_index = 1,
    
    -- 行动顺序配置
    action_order_config = {
        type = "speed_based", -- speed_based, action_point, fixed
        ap_threshold = 100, -- 行动值阈值（用于action_point模式）
        ap_regen_rate = 10, -- 每回合行动值恢复率（用于action_point模式）
        random_factor = 10 -- 随机因素范围
    },
    
    -- 角色行动值（用于action_point模式）
    character_ap = {},
    
    -- 战斗统计信息
    battle_stats = {
        total_damage_dealt = 0,
        total_damage_taken = 0,
        total_healing_done = 0,
        total_skills_used = 0,
        total_items_used = 0,
        total_status_effects_applied = 0
    },
    
    -- 战斗结果
    result = {
        winner_team_id = nil,
        reason = "",
        rewards = {
            exp = 0,
            gold = 0,
            items = {}
        }
    }
}

-- 战斗状态构造函数
function BattleState:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    o:init()
    return o
end

-- 初始化战斗状态
function BattleState:init()
    self.battle_id = "battle_" .. os.time() .. "_" .. math.random(1000, 9999)
    self.battle_state = self.states.WAITING
    self.start_time = 0
    self.end_time = 0
    self.teams = {
        [1] = {
            name = "Team 1",
            characters = {},
            score = 0
        },
        [2] = {
            name = "Team 2",
            characters = {},
            score = 0
        }
    }
    self.characters = {}
    self.current_turn = 0
    self.max_turns = 100
    self.turn_order = {}
    self.current_character_index = 1
    self.action_order_config = {
        type = "speed_based",
        ap_threshold = 100,
        ap_regen_rate = 10,
        random_factor = 10
    }
    self.character_ap = {}
    self.battle_stats = {
        total_damage_dealt = 0,
        total_damage_taken = 0,
        total_healing_done = 0,
        total_skills_used = 0,
        total_items_used = 0,
        total_status_effects_applied = 0
    }
    self.result = {
        winner_team_id = nil,
        reason = "",
        rewards = {
            exp = 0,
            gold = 0,
            items = {}
        }
    }
    
    Logger.debug("战斗状态初始化完成，战斗ID: " .. self.battle_id)
end

-- 设置战斗队伍
function BattleState:set_teams(team1, team2)
    -- 设置队伍1
    self.teams[1].characters = team1 or {}
    for _, character in ipairs(self.teams[1].characters) do
        character.team_id = 1
        table.insert(self.characters, character)
    end
    
    -- 设置队伍2
    self.teams[2].characters = team2 or {}
    for _, character in ipairs(self.teams[2].characters) do
        character.team_id = 2
        table.insert(self.characters, character)
    end
    
    Logger.info("战斗队伍设置完成，队伍1: " .. #self.teams[1].characters .. " 人，队伍2: " .. #self.teams[2].characters .. " 人")
end

-- 开始战斗
function BattleState:start()
    if self.battle_state ~= self.states.WAITING then
        Logger.warn("战斗已经开始或结束，无法再次开始")
        return false
    end
    
    self.battle_state = self.states.STARTING
    self.start_time = os.time()
    
    -- 初始化回合
    self:init_turn()
    
    self.battle_state = self.states.IN_PROGRESS
    
    Logger.info("战斗开始！战斗ID: " .. self.battle_id)
    Logger.info("队伍1: " .. self.teams[1].name .. "，成员: " .. #self.teams[1].characters .. " 人")
    Logger.info("队伍2: " .. self.teams[2].name .. "，成员: " .. #self.teams[2].characters .. " 人")
    
    return true
end

-- 结束战斗
function BattleState:end_battle(winner_team_id, reason)
    if self.battle_state ~= self.states.IN_PROGRESS then
        Logger.warn("战斗未在进行中，无法结束")
        return false
    end
    
    self.battle_state = self.states.ENDED
    self.end_time = os.time()
    
    -- 设置战斗结果
    self.result.winner_team_id = winner_team_id
    self.result.reason = reason or ""
    
    -- 计算战斗奖励
    self:calculate_rewards()
    
    Logger.info("战斗结束！战斗ID: " .. self.battle_id)
    Logger.info("获胜队伍: " .. (winner_team_id and self.teams[winner_team_id].name or "平局"))
    Logger.info("结束原因: " .. reason)
    Logger.info("战斗时长: " .. (self.end_time - self.start_time) .. " 秒")
    Logger.info("总回合数: " .. self.current_turn)
    
    -- 输出战斗统计信息
    self:print_battle_stats()
    
    return true
end

-- 初始化回合
function BattleState:init_turn()
    self.current_turn = self.current_turn + 1
    self.current_character_index = 1
    
    -- 计算行动顺序
    self:calculate_turn_order()
    
    Logger.info("第 " .. self.current_turn .. " 回合开始！")
    Logger.info("行动顺序: " .. self:get_turn_order_string())
end

-- 计算行动顺序
function BattleState:calculate_turn_order()
    self.turn_order = {}
    
    -- 过滤出存活的角色
    local alive_characters = {}
    for _, character in ipairs(self.characters) do
        if character.is_alive then
            table.insert(alive_characters, character)
        end
    end
    
    -- 如果没有角色存活，结束战斗
    if #alive_characters == 0 then
        self:end_battle(nil, "所有角色阵亡")
        return
    end
    
    -- 根据行动顺序类型计算行动顺序
    local action_order_type = self.action_order_config.type
    
    if action_order_type == "speed_based" then
        -- 基于速度属性的行动顺序
        self:calculate_speed_based_order(alive_characters)
    elseif action_order_type == "action_point" then
        -- 基于行动值的行动顺序
        self:calculate_action_point_order(alive_characters)
    elseif action_order_type == "fixed" then
        -- 固定行动顺序
        self:calculate_fixed_order(alive_characters)
    else
        -- 默认使用基于速度的行动顺序
        Logger.warn("未知的行动顺序类型: " .. action_order_type .. "，使用默认的基于速度的行动顺序")
        self:calculate_speed_based_order(alive_characters)
    end
end

-- 计算基于速度属性的行动顺序
function BattleState:calculate_speed_based_order(characters)
    -- 创建角色引用的浅拷贝（保持元表）
    local characters_copy = {}
    for i, character in ipairs(characters) do
        characters_copy[i] = character
        Logger.debug("复制角色 " .. i .. ": " .. (character.name or "Unknown") .. ", 速度: " .. (character.speed or 0))
    end

    Logger.debug("开始排序，共 " .. #characters_copy .. " 个角色")

    -- 安全的排序函数，确保不会抛出异常
    local function safe_sort_compare(a, b)
        if not a or not b then
            Logger.debug("排序比较中发现nil值")
            return false
        end

        -- 使用简单的速度属性比较，避免调用方法
        local speed_a = a.speed or 0
        local speed_b = b.speed or 0
        local result = speed_a > speed_b

        Logger.debug("排序比较: " .. (a.name or "Unknown") .. "(" .. speed_a .. ") vs " .. (b.name or "Unknown") .. "(" .. speed_b .. ") = " .. tostring(result))
        return result
    end

    -- 使用安全的排序函数
    for i = 1, #characters_copy do
        for j = i + 1, #characters_copy do
            if safe_sort_compare(characters_copy[j], characters_copy[i]) then
                local temp = characters_copy[i]
                characters_copy[i] = characters_copy[j]
                characters_copy[j] = temp
            end
        end
    end

    -- 设置行动顺序
    self.turn_order = characters_copy

    Logger.debug("排序完成")
end

-- 计算基于行动值的行动顺序
function BattleState:calculate_action_point_order(characters)
    -- 初始化或更新角色行动值
    for _, character in ipairs(characters) do
        if not self.character_ap[character.id] then
            self.character_ap[character.id] = 0
        end
        
        -- 恢复行动值
        local ap_regen = character.speed * (self.action_order_config.ap_regen_rate / 100)
        self.character_ap[character.id] = self.character_ap[character.id] + ap_regen
        Logger.debug(character.name .. " 恢复了 " .. ap_regen .. " 行动值，当前行动值: " .. self.character_ap[character.id])
    end
    
    -- 按行动值排序（降序）
    local characters_copy = TableUtils.deep_copy(characters)
    table.sort(characters_copy, function(a, b) 
        return self.character_ap[a.id] > self.character_ap[b.id] 
    end)
    
    -- 设置行动顺序
    self.turn_order = characters_copy
end

-- 计算固定行动顺序
function BattleState:calculate_fixed_order(characters)
    -- 固定顺序：队伍1角色按位置顺序，然后是队伍2角色按位置顺序
    local team1_characters = {}
    local team2_characters = {}
    
    for _, character in ipairs(characters) do
        if character.team_id == 1 then
            table.insert(team1_characters, character)
        else
            table.insert(team2_characters, character)
        end
    end
    
    -- 按位置排序
    table.sort(team1_characters, function(a, b) return a.position < b.position end)
    table.sort(team2_characters, function(a, b) return a.position < b.position end)
    
    -- 合并队伍
    self.turn_order = {}
    for _, character in ipairs(team1_characters) do
        table.insert(self.turn_order, character)
    end
    for _, character in ipairs(team2_characters) do
        table.insert(self.turn_order, character)
    end
end

-- 获取行动顺序字符串
function BattleState:get_turn_order_string()
    local order_str = ""
    for i, character in ipairs(self.turn_order) do
        if i > 1 then
            order_str = order_str .. " -> "
        end
        order_str = order_str .. character.name
    end
    return order_str
end

-- 获取当前行动角色
function BattleState:get_current_character()
    if #self.turn_order == 0 then
        return nil
    end
    
    return self.turn_order[self.current_character_index]
end

-- 推进到下一个角色
function BattleState:next_character()
    -- 获取当前行动的角色
    local current_character = self:get_current_character()
    
    -- 如果是行动值模式，消耗行动值
    if self.action_order_config.type == "action_point" and current_character then
        -- 消耗行动值
        self.character_ap[current_character.id] = self.character_ap[current_character.id] - self.action_order_config.ap_threshold
        Logger.debug(current_character.name .. " 消耗了 " .. self.action_order_config.ap_threshold .. " 行动值，剩余行动值: " .. self.character_ap[current_character.id])
    end
    
    self.current_character_index = self.current_character_index + 1
    
    -- 检查是否回合结束
    if self.current_character_index > #self.turn_order then
        -- 回合结束，更新所有角色的状态效果
        self:update_all_status_effects()
        
        -- 检查战斗是否结束
        if self:check_battle_end_conditions() then
            return nil
        end
        
        -- 开始新回合
        self:init_turn()
    end
    
    return self:get_current_character()
end

-- 更新所有角色的状态效果
function BattleState:update_all_status_effects()
    for _, character in ipairs(self.characters) do
        character:update_status_effects()
    end
end

-- 检查战斗结束条件
function BattleState:check_battle_end_conditions()
    -- 检查回合数
    if self.current_turn >= self.max_turns then
        self:end_battle(nil, "回合数达到上限")
        return true
    end
    
    -- 检查队伍存活情况
    local team1_alive = false
    local team2_alive = false
    
    for _, character in ipairs(self.characters) do
        if character.is_alive then
            if character.team_id == 1 then
                team1_alive = true
            elseif character.team_id == 2 then
                team2_alive = true
            end
        end
    end
    
    if not team1_alive and not team2_alive then
        self:end_battle(nil, "双方队伍全灭")
        return true
    elseif not team1_alive then
        self:end_battle(2, "队伍1全灭")
        return true
    elseif not team2_alive then
        self:end_battle(1, "队伍2全灭")
        return true
    end
    
    return false
end

-- 更新战斗统计信息
function BattleState:update_battle_stats(stats)
    if stats.damage_dealt then
        self.battle_stats.total_damage_dealt = self.battle_stats.total_damage_dealt + stats.damage_dealt
    end
    if stats.total_damage_dealt then
        self.battle_stats.total_damage_dealt = self.battle_stats.total_damage_dealt + stats.total_damage_dealt
    end

    if stats.damage_taken then
        self.battle_stats.total_damage_taken = self.battle_stats.total_damage_taken + stats.damage_taken
    end

    if stats.healing_done then
        self.battle_stats.total_healing_done = self.battle_stats.total_healing_done + stats.healing_done
    end
    if stats.total_healing_done then
        self.battle_stats.total_healing_done = self.battle_stats.total_healing_done + stats.total_healing_done
    end

    if stats.skills_used then
        self.battle_stats.total_skills_used = self.battle_stats.total_skills_used + stats.skills_used
    end
    if stats.total_skills_used then
        self.battle_stats.total_skills_used = self.battle_stats.total_skills_used + stats.total_skills_used
    end
    
    if stats.items_used then
        self.battle_stats.total_items_used = self.battle_stats.total_items_used + stats.items_used
    end
    
    if stats.status_effects_applied then
        self.battle_stats.total_status_effects_applied = self.battle_stats.total_status_effects_applied + stats.status_effects_applied
    end
end

-- 计算战斗奖励
function BattleState:calculate_rewards()
    -- 简化处理，实际应该根据战斗难度、敌人等级等计算奖励
    self.result.rewards = {
        exp = 100 * self.current_turn,
        gold = 50 * self.current_turn,
        items = {}
    }
end

-- 输出战斗统计信息
function BattleState:print_battle_stats()
    Logger.info("战斗统计信息:")
    Logger.info("总伤害输出: " .. self.battle_stats.total_damage_dealt)
    Logger.info("总伤害承受: " .. self.battle_stats.total_damage_taken)
    Logger.info("总治疗量: " .. self.battle_stats.total_healing_done)
    Logger.info("总技能使用次数: " .. self.battle_stats.total_skills_used)
    Logger.info("总物品使用次数: " .. self.battle_stats.total_items_used)
    Logger.info("总状态效果施加次数: " .. self.battle_stats.total_status_effects_applied)
end

-- 获取战斗状态快照
function BattleState:get_snapshot()
    local snapshot = {
        battle_id = self.battle_id,
        battle_state = self.battle_state,
        current_turn = self.current_turn,
        max_turns = self.max_turns,
        teams = {},
        characters = {},
        turn_order = {},
        current_character_index = self.current_character_index,
        battle_stats = TableUtils.deep_copy(self.battle_stats),
        result = TableUtils.deep_copy(self.result)
    }
    
    -- 复制队伍信息
    for team_id, team in pairs(self.teams) do
        snapshot.teams[team_id] = {
            name = team.name,
            score = team.score,
            characters = {}
        }
        
        for _, character in ipairs(team.characters) do
            table.insert(snapshot.teams[team_id].characters, character:get_state())
        end
    end
    
    -- 复制角色信息
    for _, character in ipairs(self.characters) do
        table.insert(snapshot.characters, character:get_state())
    end
    
    -- 复制行动顺序
    for _, character in ipairs(self.turn_order) do
        table.insert(snapshot.turn_order, character.id)
    end
    
    return snapshot
end

-- 导出模块
return BattleState